import os
import re
import requests
from ipaddress import IPv4Address, AddressValueError
import time
import random
from bs4 import BeautifulSoup

def extract_ips_from_eml(file_path):
    """从eml文件中提取所有IP地址"""
    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
        content = f.read()

    ip_pattern = r'\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b'
    return re.findall(ip_pattern, content)

def is_private_ip(ip_str):
    """判断是否为内网地址"""
    try:
        ip = IPv4Address(ip_str)
        return ip.is_private or ip.is_loopback or ip.is_link_local
    except AddressValueError:
        return False

def get_ip138_location(ip):
    """通过ip138查询IP地理位置（稳定版）"""
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
        'Referer': 'https://www.ip138.com/',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.9',
        'DNT': '1',
        'Connection': 'keep-alive'
    }

    try:
        # 添加随机延迟防止被封
        time.sleep(random.uniform(1, 3))

        response = requests.get(
            f'https://www.ip138.com/iplookup.php?ip={ip}',
            headers=headers,
            timeout=15
        )
        response.encoding = 'utf-8'

        # 使用BeautifulSoup解析HTML
        soup = BeautifulSoup(response.text, 'html.parser')

        # # 方案1：通过表格结构定位
        # location_td = soup.find('td', string='IP的物理地址：')
        # if location_td:
        #     return location_td.find_next('td').get_text(strip=True)

        # 方案2：备用定位方式
        result_div = soup.find('div', class_='module')
        if result_div:
            # return result_div.get_text(' ', strip=True).split('的物理地址：')[-1].strip()
            full_text = result_div.get_text(' ', strip=True)

            # 使用正则表达式精确匹配中国+省市区格式
            location_match = re.search(r'(中国[\u4e00-\u9fa5]+省[\u4e00-\u9fa5]+市[\u4e00-\u9fa5]+区)', full_text)
            if location_match:
                return location_match.group(1)
        # # 方案3：正则提取
        # match = re.search(r'IP的物理地址[：:]\s*([^<]+)', response.text)
        # if match:
        #     return match.group(1).strip()

        return "未找到地理位置信息"

    except Exception as e:
        return f"查询失败: {str(e)}"

def main():
    eml_files = [f for f in os.listdir('.') if f.lower().endswith('.eml')]

    if not eml_files:
        print("当前目录下未找到.eml文件")
        return

    print(f"发现 {len(eml_files)} 个eml文件，开始解析...")

    all_ips = []
    for eml_file in eml_files:
        try:
            ips = extract_ips_from_eml(eml_file)
            if ips:
                print(f"文件 {eml_file} 发现 {len(ips)} 个IP地址")
                all_ips.extend(ips)
        except Exception as e:
            print(f"处理文件 {eml_file} 时出错: {str(e)}")

    if not all_ips:
        print("未提取到任何IP地址")
        return

    unique_ips = list(set(all_ips))
    public_ips = [ip for ip in unique_ips if not is_private_ip(ip)]

    print(f"\n发现 {len(public_ips)} 个公网IP地址：")
    for ip in public_ips:
        print(f"正在查询 {ip} ...")
        location = get_ip138_location(ip)
        print(f"{ip}\t{location}")

if __name__ == "__main__":
    main()
